<template>
  <div class="main">
    <div ref="map" class="map"></div>
    <div class="legend">
      <div class="legend-item" @click="toggleLayer('ZC')">
        <div class="icon">
          <img src="./assets/l_zc.png" width="60" />
        </div>
        <div class="name">猪场</div>
      </div>
      <div class="legend-item" @click="toggleLayer('SLC')">
        <div class="icon">
          <img src="./assets/l_slc.png" width="60" />
        </div>
        <div class="name">饲料专供厂</div>
      </div>
      <div class="legend-item" @click="toggleLayer('TZC')">
        <div class="icon">
          <img src="./assets/l_tzc.png" width="60" />
        </div>
        <div class="name">屠宰厂</div>
      </div>
      <div class="legend-item" @click="toggleLayer('YB')">
        <div class="icon">
          <img src="./assets/l_yb.png" width="60" />
        </div>
        <div class="name">疫病</div>
      </div>
    </div>
  </div>
</template>

<script>
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css'
import backgroundImg from './assets/backgroundImg.png';

const shengGeojson = require('./assets/data/china.json'); // 中国各省面状数据
const provincePoints = require('./assets/data/provincePoints.json'); // 省中心点数据，调整后

let map;
export default {
  components: {
  },
  mixins: [],
  props: {
    locating: {
      type: Object,
      default: () => ({}),
    },
    attr: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      mapboxgl_: null,
      iconImgs: [
        {
          name: 'zcMarkerRed',
          value: require('./assets/zc_red.png'),
        }, {
          name: 'zcMarkerGrey',
          value: require('./assets/zc_grey.png'),
        }, {
          name: 'zcMarkerGreen',
          value: require('./assets/zc_green.png'),
        }, {
          name: 'tzcMarkerRed',
          value: require('./assets/tz_red.png'),
        }, {
          name: 'tzcMarkerGrey',
          value: require('./assets/tz_grey.png'),
        }, {
          name: 'tzcMarkerGreen',
          value: require('./assets/tz_green.png'),
        }, {
          name: 'slcMarkerRed',
          value: require('./assets/sl_red.png'),
        }, {
          name: 'slcMarkerGrey',
          value: require('./assets/sl_grey.png'),
        }, {
          name: 'slcMarkerGreen',
          value: require('./assets/sl_green.png'),
        }, {
          name: 'ybMarker',
          value: require('./assets/l_yb.png'),
        }],
      dateType: 'M',
      dateTime: '2022-07',
      onlyShowSL: false,
      onlyShowTZ: false,
      onlyShowYB: false,
      onlyShowZC: false,
      operateOk: false,
      hoveredLabelStateId: null,
      hoveredZCstateId: null,
      hoveredYBstateId: null,
      gifMarkerIds: [], // 动图

      hoveredIcon: false, // hover在某些图标上标识，解决省面指针状态错乱
    };
  },
  watch: {
    attr: {
      handler() {
        this.$nextTick(() => {
          this.resize();
        });
      },
      deep: true,
    },
    locating: {
      handler() {
        this.resize();
      },
      deep: true,
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.initialize();

      const handler = setInterval(() => {
        if (this.operateOk ) {
          clearInterval(handler);

          this.initBusiness();
          this.bindEvents();
        }
      }, 100);
    });
  },
  beforeUnmount() {
    this.clearBusiness();
    this.removeMarkers();
    this.map && this.map.remove();
    this.map = null;
  },
  methods: {
    validateData(data) {
      return JSON.parse(data);
    },
    interfaceRequestData() {
    },
    customHandleByParamsHandler() {
      if (!this.map || !this.operateOk) return;
      this.initBusiness();
    },
    initialize() {
      mapboxgl.accessToken = 'pk.eyJ1Ijoiemhlbmd5dWFuMDEiLCJhIjoiY2tweHJuaWMyMDd4aDJ2cGR4azJpMHA3ZyJ9.2uE3aEVVqriGOKNU11xEnw';
      map = new mapboxgl.Map({
        container: this.$refs.map,
        style: 'mapbox://styles/zhengyuan01/ckx43v0rp2ycm14oi5d75gnd3', // 空背景
        center: [102.58618575665429, 34.528282169460226],
        maxZoom: 10,
        minZoom: 4.0,
        maxBounds: [
          [31.83136873800271, 12.976677829309509],
          [166.79021853721116, 69.3686679265974],
        ],
        clickTolerance: 5,
        // testMode:true,
        dragRotate: false,
        touchPitch: false,
        pitch: 50,
        pitchWithRotate: false,
        renderWorldCopies: false,
      });
      this.map = map;
      window.map = map;
      map.on('load', () => {
        // 注册image icon
        this.iconImgs.forEach((obj) => {
          const { name, value } = obj;
          map.loadImage(value, (error, image) => {
            if (error) throw error;
            if (!map.hasImage(name)) {
              map.addImage(name, image);
            }
          });
        });

        this.map.addLayer({
          id: 'layer-image',
          type: 'raster',
          source: {
            type: 'image',
            url: backgroundImg,
            coordinates: [
              [60, 58],
              [150, 58],
              [150, 10],
              [60, 10],
            ],
          },
          paint: {
            'raster-fade-duration': 0,
          },
        });

        this.fitBounds();
        // this.map.setMinZoom(4.0); // 因为有padding 这里+
        this.operateOk = true;
      });
    },
    initBusiness() {
      if (!this.map) return;

      this.hoveredZCstateId = null;
      this.hoveredYBstateId = null;
      this.operateOk = false;
      this.clearBusiness();
      this.removeMarkers();
      this.fitBounds();


          this.map.addSource('source-sheng-polygon', {
            type: 'geojson',
            data: shengGeojson,
          });
          // 省面图层
          this.map.addLayer({
            id: 'layer-sheng-polygon',
            type: 'fill',
            source: 'source-sheng-polygon',
            layout: {
              visibility: 'visible',
            },
            paint: {
              'fill-color': [
                'case',
                ['in', ['get', 'name'], ['literal', ['青海省', '台湾省', '西藏自治区']]],
                '#565E6F',
                '#1C436A',
              ],
              'fill-opacity': [
                'case',
                ['in', ['get', 'name'], ['literal', ['青海省', '台湾省', '西藏自治区']]],
                0.5,
                1,
              ],
            },
          });

          // 省名字图层
          this.map.addSource('source-sheng-label', {
            type: 'geojson',
            data: provincePoints,
          });
          this.map.addLayer({
            id: 'layer-sheng-label',
            type: 'symbol',
            source: 'source-sheng-label',
            paint: {
              'text-color': '#ddd',
            },
            layout: {
              'text-field': ['get', 'name'],
              'text-allow-overlap': true,
              'text-size': 16,
              'text-font': ['PingFangSC'],
            },
          });

          // 省界线 layer
          this.map.addLayer({
            id: 'layer-sheng-line',
            type: 'line',
            source: 'source-sheng-polygon',
            layout: {
              visibility: 'visible',
            },
            paint: {
              'line-color': '#0cc7c7', // 0cc7c7
              'line-width': [
                'case',
                ['==', ['get', 'name'], '中国'],
                8,
                ['==', ['get', 'name'], '山东东营'],
                2,
                2,
              ],
              'line-dasharray': [
                'match',
                ['get', 'name'],
                '山东东营',
                ['literal', [1, 1]],
                ['literal', [1, 0]],
              ],
            },
          });
          

          // 省利润颜色
          shengGeojson.features.forEach((item) => {
              const png = Math.random() > 0.5 ? `./assets/province/green/${item.properties.provinceName}.png` :
                `./assets/province/red/${item.properties.provinceName}.png`;
              const sourceId = `source-image-${item.properties.provinceName}`;
              const layerId = `layer-image-${item.properties.provinceName}`;
              if (this.map.getLayer(layerId)) {
                this.map.removeLayer(layerId);
              }
              if (this.map.getSource(sourceId)) {
                this.map.removeSource(sourceId);
              }

              this.map.addSource(sourceId, {
                type: 'image',
                url: require(`${png}`),
                coordinates: [
                  [
                    72.36953019412131,
                    55.156841331359324,
                  ], [
                    137.090411817035942,
                    55.156841331359324,
                  ], [
                    137.090411817035942,
                    16.434946343290733,
                  ], [
                    72.36953019412131,
                    16.434946343290733,
                  ]],
              });
              this.map.addLayer({
                id: layerId,
                // id: `layer-image-${item.properties.provinceName}`,
                type: 'raster',
                source: sourceId,
                paint: {
                  'raster-fade-duration': 0,
                },
              }, 'layer-tzc');
          });
    },
    fitBounds() {
      this.map.fitBounds([
        72.59056663474246,
        21.2285556789015,
        132.80803871111766,
        50.519197463692024,
      ], {
        duration: 800,
        easing: (t) => t * t * t,
        linear: true,
        pitch: 50,
        padding: {
          top: -350,
          bottom: 0,
          right: 0,
          left: 0,
        },
      });
    },
    clearBusiness() {
      if (!this.map) return;
      const layers = [
        'layer-tzc', 'layer-slc', 'layer-zc', 'layer-boundary-polygon', 'layer-sheng-polygon',
        'layer-sheng-line', 'layer-sheng-label', 'layer-yb',
      ];

      layers.forEach((l) => {
        if (this.map.getLayer(l)) {
          this.map.removeLayer(l);
        }
      });

      const sources = [
        'source-tzc', 'source-slc', 'source-zc', 'source-boundary-polygon', 'source-sheng-polygon',
        'source-sheng-label', 'source-yb',
      ];

      sources.forEach((s) => {
        if (this.map.getSource(s)) {
          this.map.removeSource(s);
        }
      });
    },
    // 图例切换
    toggleLayer(name) {
      if (!this.operateOk) return;
      this.resetIcon();
      this.triggerEvent('triggerDialogClose', {});

      const focusLayers = []; // 聚焦图层
      let showFlag = false;
      switch (name) {
        case 'YB':
          this.map.setLayoutProperty(
            'layer-yb',
            'visibility',
            'visible',
          );
          focusLayers.push('layer-yb');
          showFlag = this.onlyShowYB = !this.onlyShowYB;
          break;
        case 'SLC':
          this.map.setLayoutProperty(
            'layer-slc',
            'visibility',
            'visible',
          );
          focusLayers.push('layer-slc');
          showFlag = this.onlyShowSL = !this.onlyShowSL;
          break;
        case 'TZC':
          this.map.setLayoutProperty(
            'layer-tzc',
            'visibility',
            'visible',
          );
          focusLayers.push('layer-tzc');
          showFlag = this.onlyShowTZ = !this.onlyShowTZ;
          break;
        case 'ZC':
          this.map.setLayoutProperty(
            'layer-zc',
            'visibility',
            'visible',
          );
          this.map.setLayoutProperty(
            'layer-yb',
            'visibility',
            'visible',
          );
          focusLayers.push('layer-zc');
          focusLayers.push('layer-yb');
          showFlag = this.onlyShowZC = !this.onlyShowZC;
          break;
        default:
          break;
      }

      const layers = ['layer-yb', 'layer-slc', 'layer-tzc', 'layer-zc'];
      focusLayers.forEach((item) => {
        layers.splice(layers.indexOf(item), 1);
      });

      layers.forEach((item) => {
        this.map.setLayoutProperty(
          item,
          'visibility',
          showFlag ? 'none' : 'visible',
        );
      });
    },
    bindEvents() {
      if (!this.map) return;
      const that = this;
      const popup = new mapboxgl.Popup({
        closeButton: false,
        closeOnClick: false,
        className: 'hover-popup',
        offset: {
          bottom: [0, -20],
        },
      });
      map.on('click', 'layer-sheng-polygon', (e) => {
        const features = map.queryRenderedFeatures(e.point);
        if (features[0].layer.id === 'layer-sheng-polygon') {
          const { name } = e.features[0].properties;
          if (name.includes('内蒙古')) {
            // 进入省份产业链二屏
            if (!this.attr.previewScreenId) return;
            // 携带参数路由跳转
            const routeParams = {
              ...this.store.state.filterArgs,
              // ...this.eventParams,
              ...this.parseParams().params,
            };

            window.sessionStorage.setItem('routeParams', JSON.stringify(routeParams));
            this.$router.replace({
              name: 'previewScreen',
              params: routeParams,
              query: {
                id: this.attr.previewScreenId,
              },
            });
          }
        }
      });

      // 猪厂点击
      map.on('click', 'layer-zc', (e) => {
        e.preventDefault();
        this.resetIcon();

        if (e.features[0]?.properties?.provinceName === '内蒙古') {
          const { id } = e.features[0];
          that.hoveredZCstateId = id;
          map.setFeatureState(
            { source: 'source-zc', id: that.hoveredZCstateId },
            { click: true },
          );
          document.getElementById(`zc-${id}`).style.display = 'block';
        }
        this.triggerDialogOpen(e.features[0].properties);
        if (this.attr.farmCodes.includes(e.features[0].properties?.farmCode)) {
          this.triggerGoToNext(e.features[0].properties);
        }
      });

      // 疫病点击
      map.on('click', 'layer-yb', (e) => {
        e.preventDefault();
        that.resetIcon();

        if (e.features[0]?.properties?.provinceName === '内蒙古') {
          const { id } = e.features[0];
          that.hoveredYBstateId = id;
          map.setFeatureState(
            { source: 'source-yb', id: that.hoveredYBstateId },
            { click: true },
          );
          document.getElementById(`yb-${id}`).style.display = 'block';
        }
        this.triggerDialogOpen(e.features[0].properties);
        if (this.attr.farmCodes.includes(e.features[0].properties?.farmCode)) {
          this.triggerGoToNext(e.features[0].properties);
        }
      });

      map.on('mousemove', (e) => {
        const features = map.queryRenderedFeatures(e.point, { layers: ['layer-zc', 'layer-yb', 'layer-slc', 'layer-tzc'] });
        // console.log(features);
        if (features.length) {
          let description = '';
          if (['layer-zc', 'layer-yb'].includes(features[0].layer.id)) {
            // map.getCanvas().style.cursor = 'pointer';
            // 只有内蒙古的显示可点击状态
            map.getCanvas().style.cursor = features[0].properties.provinceName === '内蒙古' ? 'pointer' : 'default';
            description = features[0].properties.farmName;
          } else if (['layer-slc', 'layer-tzc'].includes(features[0].layer.id)) {
            map.getCanvas().style.cursor = 'default';
            this.hoveredIcon = true;
            description = features[0].properties.compName;
          }
          const coordinates = features[0].geometry.coordinates.slice();
          while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
            coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
          }
          popup.setLngLat(coordinates).setHTML(description).addTo(map);
        } else {
          popup.remove();
          map.getCanvas().style.cursor = '';
          this.hoveredIcon = false;
        }

        const shengFeatures = map.queryRenderedFeatures(e.point, { layers: ['layer-sheng-polygon'] });

        if (this.hoveredIcon) return;

        if (shengFeatures.length > 0) {
          const { name } = shengFeatures[0].properties;
          if (name.includes('内蒙古')) {
            map.getCanvas().style.cursor = 'pointer';
          }
        }
      });

      // 右击菜单
      map.on('contextmenu', () => {
        this.fitBounds();
      });
    },
    resetIcon() {
      if (this.hoveredZCstateId) {
        this.map.setFeatureState(
          { source: 'source-zc', id: this.hoveredZCstateId },
          { click: false },
        );
        document.getElementById(`zc-${this.hoveredZCstateId}`).style.display = 'none';
        this.hoveredZCstateId = null;
      }
      if (this.hoveredYBstateId) {
        this.map.setFeatureState(
          { source: 'source-yb', id: this.hoveredYBstateId },
          { click: false },
        );
        document.getElementById(`yb-${this.hoveredYBstateId}`).style.display = 'none';
        this.hoveredYBstateId = null;
      }
    },
    removeMarkers() {
      this.gifMarkerIds.forEach((id) => {
        document.getElementById(id) && document.getElementById(id).remove();
      });
      this.gifMarkerIds = [];
    },
    format(num) {
      const reg = /\d{1,3}(?=(\d{3})+$)/g;
      return (`${num}`).replace(reg, '$&,');
    },
    triggerDialogOpen(data) {
      // this.triggerEvent('triggerDialogOpen', data);
      // 只有属于内蒙古的 才打开右侧弹窗 不然就关闭右侧弹窗显示中国区
      if (data.provinceName === '内蒙古') {
        this.triggerEvent('triggerDialogOpen', data);
      } else {
        this.triggerEvent('triggerDialogClose', {});
      }
    },
    triggerGoToNext(data) {
      // this.triggerEvent('triggerGoToNext', data);
      // 只有属于内蒙古省的才触发事件 farmcode有相同的
      if (data.provinceName === '内蒙古') {
        this.triggerEvent('triggerGoToNext', data);
      }
    },
    // 导出json文件
    exportFileJSON(data = {}, filename = 'dataJSON.json') {
      let dataCopy = data;
      if (typeof dataCopy === 'object') {
        dataCopy = JSON.stringify(dataCopy, null, 4);
      }
      // 导出数据
      const blob = new Blob([data], { type: 'text/json' });
      const e = new MouseEvent('click');
      const a = document.createElement('a');

      a.download = filename;
      a.href = window.URL.createObjectURL(blob);
      a.dataset.downloadurl = ['text/json', a.download, a.href].join(':');
      a.dispatchEvent(e);
    },
    resize() {
      this.map && this.map.resize();
    },
  },
};
</script>
<style>
/* @import "mapbox-gl/dist/mapbox-gl.css"; */
</style>
<style lang="less" scoped>
.main {
  height: 100%;
  .map {
    height: 100%;
  }
  .legend {
    position: fixed;
    bottom: 15px;
    left: 15px;
    &-item {
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      margin-bottom: 10px;
      .icon {
        width: 20%;
        display: flex;
        align-items: center;
      }
      .name {
        font-family: PingFangSC-Regular;
        font-size: 30px;
        color: #fff;
        font-weight: 600;
        margin-left: 30px;
        line-height: 60px;
        height: 60px;
      }
    }
  }
}

/deep/ .hover-popup {
  max-width: unset !important;
}

/deep/ .hover-popup .mapboxgl-popup-tip {
  border-top-color: #1c436a;
  display: none;
}
/deep/ .hover-popup .mapboxgl-popup-content {
  background: black;
  border: 1px solid #1c436a;
  color: #fff;
  font-size: 28px;
  padding: 12px;
}
/deep/ .mapboxgl-ctrl {
  &-bottom-left {
    display: none;
  }
  &-bottom-right {
    display: none;
  }
}
</style>
